########  Interface  for serde ######

class Map(object):
    #TODO: add more functions
    # insert_..
    # remove
    # update & repace 
    # for_each
    # iter
    def __str__(self):
        return "Map__Interface"

class Value(object):
    #TODO: add more functions
    # is_xx()
    # get_xx()
    def __str__(self):
        return "Value__Interface"

class Serde(object):
    def from_str(self, src):
        raise NotImplementedError()
    def to_str(self, map):
        raise NotImplementedError()

class SerdeGtp(Serde):
    def __str__(self):
        return "SerdeGtp__Interface"


class MapValueFactory(object) : 
    def createMap(self):
        return Map()

    def createValue(self):
        return Value()

    def createSerdeGtp(self):
        return SerdeGtp()



class SerdeFactory(object):
    @staticmethod
    def create(type=None):
        if type == "C" : 
            return MapValueFactoryC()
        elif type == "RUST":
            return MapValueFactoryRust()
        elif type == "PYTHON":
            return MapValueFactoryPython()
        else :
            return MapValueFactoryPython()



########  Python Impl ######  python_impl.py

class MapPython(Map):
    def __str__(self):
        return "Map__Python"
class ValuePython(Value):
    def __str__(self):
        return "Value__Python"

class SerdeGtpPython(SerdeGtp):
    def __str__(self):
        return "SerdeGtp__Python"

class MapValueFactoryPython(MapValueFactory):
    def createMap(self):
        return MapPython()
    def createValue(self):
        return ValuePython()

    def createSerdeGtp(self):
        return SerdeGtpPython()




######## Rust Impl ###### rust_impl.py

class MapRust(Map):
    def __str__(self):
        return "Map__Rust"
class ValueRust(Value):
    def __str__(self):
        return "Value__Rust"

class SerdeGtpRust(SerdeGtp):
    def __str__(self):
        return "SerdeGtp__Rust"

class MapValueFactoryRust(MapValueFactory):
    def createMap(self):
        return MapRust()
    def createValue(self):
        return ValueRust()
    def createSerdeGtp(self):
        return SerdeGtpRust()




########  C Impl ######  c_impl.py

class MapC(Map):
    def __str__(self):
        return "Map__C"
class ValueC(Value):
    def __str__(self):
        return "Value__C"

class SerdeGtpC(SerdeGtp):
    def __str__(self):
        return "SerdeGtp__C"

class MapValueFactoryC(MapValueFactory):
    def createMap(self):
        return MapC()
    def createValue(self):
        return ValueC()
    def createSerdeGtp(self):
        return SerdeGtpC()

        




import unittest

class MapValueFactoryTest(unittest.TestCase):
    def test_create(self):
        f = SerdeFactory.create()
        self.assertEqual("Map__Python", str(f.createMap()))
        self.assertEqual("Value__Python", str(f.createValue()))
        self.assertEqual("SerdeGtp__Python", str(f.createSerdeGtp()))

        f = SerdeFactory.create("C")
        self.assertEqual("Map__C", str(f.createMap()))
        self.assertEqual("Value__C", str(f.createValue()))
        self.assertEqual("SerdeGtp__C", str(f.createSerdeGtp()))

        f = SerdeFactory.create("PYTHON")
        self.assertEqual("Map__Python", str(f.createMap()))
        self.assertEqual("Value__Python", str(f.createValue()))
        self.assertEqual("SerdeGtp__Python", str(f.createSerdeGtp()))

        f = SerdeFactory.create("RUST")
        self.assertEqual("Map__Rust", str(f.createMap()))
        self.assertEqual("Value__Rust", str(f.createValue()))
        self.assertEqual("SerdeGtp__Rust", str(f.createSerdeGtp()))

if __name__ == "__main__":
    unittest.main()

